package org.yu.register.item;

import net.minecraft.nbt.CompoundTag;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraftforge.common.capabilities.ICapabilityProvider;
import net.minecraftforge.common.util.NonNullSupplier;
import net.minecraftforge.items.CapabilityItemHandler;
import net.minecraftforge.items.ItemStackHandler;
import org.jetbrains.annotations.Nullable;
import org.yu.api.register.LazyItemMenu;
import org.yu.api.register.MenuHolder;
import org.yu.register.capability.ItemStackProvider;

import javax.annotation.Nonnull;
import java.util.function.Supplier;

public abstract class ContainerItem extends Item {
    public ContainerItem(Properties pProperties) {
        super(pProperties);
    }
    @Nullable
    public abstract MenuHolder<? extends LazyItemMenu> getMenu();
    @Nonnull
    public abstract NonNullSupplier<ItemStackHandler> getStackHandlerSupplier();
    @Nullable
    @Override
    public ICapabilityProvider initCapabilities(ItemStack stack, @Nullable CompoundTag nbt) {
        return new ItemStackProvider(getStackHandlerSupplier());
    }
    public boolean shouldOpenGui(){
        return true;
    }
    @Nonnull
    @Override
    public InteractionResultHolder<ItemStack> use(Level pLevel, Player pPlayer, @Nonnull InteractionHand pUsedHand) {
        var item=pPlayer.getItemInHand(pUsedHand);
        if(!pLevel.isClientSide()&&pPlayer instanceof ServerPlayer serverPlayer&&shouldOpenGui()&&getMenu()!=null){
            getMenu().openItemMenu(serverPlayer,pUsedHand);
        }
        return InteractionResultHolder.success(item);
    }
    @Nullable
    @Override
    public CompoundTag getShareTag(ItemStack stack) {
        super.getShareTag(stack);
        var tag = stack.getOrCreateTag();
        stack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).ifPresent(iItemHandler -> {
            var handle=(ItemStackHandler)iItemHandler;
            tag.put("Items",handle.serializeNBT());
        });
        return tag;
    }

    @Override
    public void readShareTag(ItemStack stack, @Nullable CompoundTag nbt) {
        super.readShareTag(stack, nbt);
        if (nbt == null) {
            return;
        }
        stack.getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY).ifPresent(iItemHandler -> {
            var handle=(ItemStackHandler)iItemHandler;
            handle.deserializeNBT(nbt.getCompound("Items"));
        });
    }
    @Override
    public void onDestroyed(ItemEntity itemEntity, DamageSource damageSource) {
        var item=itemEntity.getItem();
        if(getDamage(item)==getMaxDamage(item))
            itemEntity.getItem().getCapability(CapabilityItemHandler.ITEM_HANDLER_CAPABILITY)
                    .ifPresent(iItemHandler -> {
                        var handle=(ItemStackHandler)iItemHandler;
                        var level=itemEntity.level;
                        if(!level.isClientSide){
                            for(int index=0;index<iItemHandler.getSlots();index++){
                                ItemEntity drop=new ItemEntity(itemEntity.level,itemEntity.getX(),itemEntity.getY(),itemEntity.getZ(),handle.getStackInSlot(index).copy());
                                handle.setStackInSlot(index,ItemStack.EMPTY);
                                level.addFreshEntity(drop);
                            }
                        }
                    });
        super.onDestroyed(itemEntity, damageSource);
    }
}
